Dynamic binary optimization takes advantage of information discovered at runtime to improve the performance of binary code. Runtime optimizations include reordering code, eliminating dead code, and otherwise streamlining the original binary code.
Dynamic binary optimization may be performed when translating binary code from one instruction set architecture (ISA) to another. For example, binary code may be dynamically optimized when it is dynamically translated from 32-bit Intel® Architecture (“IA32”) to a 64-bit Intel architecture (“IA64”). Intel architecture refers to ISAs developed by Intel Corporation of Santa Clara, Calif. For convenience, the original binary code is referred to as “source binary code” and the optimized, translated binary code is referred to as “target binary code.”
Often the target binary code is native to and optimized for the machine on which it is being executed. However, the source binary code is often neither native to nor optimized for the machine. Consequently, it is often desirable to perform dynamic optimization when dynamically translating a source binary code to a target binary code. For example, source IA32 code is generally not optimized to take advantage of efficiencies available on machines running IA64 code. Therefore, the IA32 source code may be optimized as well as translated into the target IA64 code. Then, the optimized target IA64 binary code is executed.
Challenges arise when aggressively optimized binary code generates runtime exceptions. Precise handling of these runtime exceptions requires 1) that the order of the exceptions occur in the same order as they would have running the original unoptimized binary code; and 2) that the exception handlers see the same processor states as if the original unoptimized binary code had generated the exceptions.
Straightforward enforcement of precise exception handling may severely constrain dynamic binary code optimizers. For example, a dynamic binary code optimizer may not be able to move a register update down the instruction stream, passing an instruction that may generate an exception, because doing so would change the machine state seen by the exception handler. Also, the optimizer may not be able to reorder two loads that could potentially cause segmentation errors because the reordering changes the order of the possible exceptions raised by the two instructions.